package strategies;

//~--- non-JDK imports --------------------------------------------------------

import com.dukascopy.api.IBar;
import com.dukascopy.api.ITick;

//~--- JDK imports ------------------------------------------------------------

import java.util.HashMap;

public class SarLine {
    public static double                                      BREACH_THRESHOLD = 0.0001;
    public static HashMap<Strategy, HashMap<String, SarLine>> sarMap           = new HashMap<Strategy,
                                                                                     HashMap<String, SarLine>>();
    protected double   AF                  = 0.003;
    public double      breachValue         = 0.0;
    protected int      candlesAfterEP      = 0;
    protected double   currentSarValue     = 0.0;
    protected double   extremePoint        = 0.0;
    protected double   previousSarValue    = 0.0;
    protected double   tradeEntryThreshold = 0.0;
    protected double   tradeExitThreshold  = 0.0;
    public boolean     markedAsBreached    = false;
    protected LineType lineType            = LineType.MIDDLE;
    public boolean     lineRetesed         = false;
    private double localDip;

  public enum LineType { UPPER, LOWER, MIDDLE }

    ;
    public SarLine(double af, LineType lineType) {
        this.AF       = af;
        this.lineType = lineType;
    }

    public SarLine(double af, LineType lineType, double breachThreshold) {
        this.AF          = af;
        this.lineType    = lineType;
        BREACH_THRESHOLD = breachThreshold;
    }

    public double getTradeEntryThreshold() {
        return tradeEntryThreshold;
    }

    public void setTradeEntryThreshold(double tradeEntryThreshold) {
        this.tradeEntryThreshold = tradeEntryThreshold;
    }

    public double getTradeExitThreshold() {
        return this.tradeExitThreshold;
    }

    public int getCandlesAfterEP() {
        return candlesAfterEP;
    }

    public double getCurrentSarValue() {
        return currentSarValue;
    }

    public void setCurrentSarValue(double currentSarValue) {
        this.currentSarValue = currentSarValue;
    }

    public double getPreviousSarValue() {
        return previousSarValue;
    }

    public void setPreviousSarValue(double previousSarValue) {
        this.previousSarValue = previousSarValue;
    }

    public boolean isBreached(ITick tick) {
        if (((lineType == LineType.LOWER) && (tick.getBid() < currentSarValue))
                || ((lineType == LineType.UPPER) && (tick.getBid() > currentSarValue))) {
            return true;
        }

        return false;
    }

    public boolean isBreached(Strategy strategy, ITick tick, boolean reset) {
        if (!markedAsBreached
                && (((lineType == LineType.LOWER) && (tick.getBid() < currentSarValue))
                    || ((lineType == LineType.UPPER) && (tick.getBid() > currentSarValue)))) {
            markedAsBreached = true;
            breachValue      = currentSarValue;
        }

        if (markedAsBreached) {
            if (((lineType == LineType.LOWER) && (tick.getBid() < (breachValue - BREACH_THRESHOLD)))
                    || ((lineType == LineType.UPPER) && (tick.getBid() > (breachValue + BREACH_THRESHOLD)))) {
                if (reset) {
                    markedAsBreached = false;
                }

                lineRetesed = false;

                return true;
            } else if (((lineType == LineType.LOWER)
                        && (tick.getBid() > sarMap.get(strategy).get("UXL").getCurrentSarValue())) || ((lineType
                            == LineType.UPPER) && (tick.getBid()
                               < sarMap.get(strategy).get("LXL").getCurrentSarValue()))) {
                markedAsBreached = false;

                return false;
            }
        }

        return false;
    }

    public boolean isMarkedAsBreached() {
        return markedAsBreached;
    }

    public void setMarkedAsBreached(boolean markedAsBreached) {
        this.markedAsBreached = markedAsBreached;
    }

    public boolean isRetested(ITick tick) {
        if (((lineType == LineType.LOWER) && (tick.getBid() - currentSarValue) <= 0.0001)
                || ((lineType == LineType.UPPER) && (currentSarValue - tick.getBid()) <= 0.0001)) {
            return true;
        }

        return false;
    }

    public double getExtremePoint() {
        return extremePoint;
    }

    public void resetExtremePoint(double price) {
        extremePoint       = price;
        candlesAfterEP     = 0;
        tradeExitThreshold = price;
    }

    public void computeSar(IBar askbar, IBar bidbar) {
        previousSarValue = currentSarValue;
        currentSarValue  = currentSarValue + AF * (bidbar.getHigh() - currentSarValue);

        if (((lineType == LineType.UPPER) && (extremePoint > bidbar.getClose()))
                || ((lineType == LineType.LOWER) && (extremePoint < bidbar.getClose()))) {
            candlesAfterEP++;
        }
    }

    public void computeSar(ITick tick) {
        if (currentSarValue == 0.0) {
            currentSarValue = tick.getBid();
        }

        if (lineType == LineType.UPPER) {
            if (currentSarValue < tick.getBid()) {
                currentSarValue = tick.getBid();
            }

            if (extremePoint < tick.getBid()) {
                tradeExitThreshold = localDip;
                localDip = tick.getBid();
                extremePoint   = tick.getBid();
                candlesAfterEP = 0;
            }

            if ( candlesAfterEP > 20 && localDip > tick.getBid()) {
                localDip = tick.getBid();
            }
        } else if (lineType == LineType.LOWER) {
            if (currentSarValue > tick.getBid()) {
                currentSarValue = tick.getBid();
            }

            if (extremePoint > tick.getBid()) {
                tradeExitThreshold = localDip;
                localDip = tick.getBid();
                extremePoint   = tick.getBid();
                candlesAfterEP = 0;
            }

            if (candlesAfterEP > 20 && localDip < tick.getBid()) {
                localDip = tick.getBid();
            }
        }
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
